package com.ruoyi.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.annotation.Anonymous;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.domain.Article;
import com.ruoyi.domain.RecoverStation;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.mapper.ArticleMapper;
import com.ruoyi.mapper.ArticleUncheckMapper;
import com.ruoyi.service.impl.PdfParseTaskServiceImpl;
import com.ruoyi.system.mapper.SysDeptMapper;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.domain.ArticleUncheck;
import com.ruoyi.service.IArticleUncheckService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * uncheckController
 * 
 * @author ya
 * @date 2025-07-12
 */
@RestController
@RequestMapping("/uncheck/uncheck")
public class ArticleUncheckController extends BaseController
{
    @Autowired
    private IArticleUncheckService articleUncheckService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private ArticleUncheckMapper articleUncheckMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private PdfParseTaskServiceImpl pdfParseTaskService;

    /**
     * 封面路径
     */
    @Anonymous
    @PostMapping("/filePath/{id}")
    public AjaxResult coverPath(@PathVariable Long id, @RequestParam MultipartFile file) throws Exception {
        try {
            // 检查文件是否为空
            if (file.isEmpty()) {
                return AjaxResult.error("上传文件为空");
            }

            // 获取 base-path
            String basePath = "uncheckFiles/coverPath/"; // 直接在这里设置基础路径，或者从配置文件中读取

            // 指定oss保存文件路径
            String objectName = basePath + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/" + file.getOriginalFilename();
            // 上传图片，成功返回文件信息
            FileInfo fileInfo = fileStorageService.of(file).setPath(objectName).upload();

            // 设置返回结果
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", fileInfo.getUrl());
            ajax.put("fileName", fileInfo.getUrl());  // 这里的值要改为url，前端访问的地址,需要文件的地址 而不是文件名称
            ajax.put("newFileName", fileInfo.getUrl());
            ajax.put("originalFilename", file.getOriginalFilename());

            // 创建Article对象并设置ID和filePath
            ArticleUncheck articleUncheck = new ArticleUncheck();
            articleUncheck.setArticleId(id);
            articleUncheck.setCoverPath(fileInfo.getUrl());

            // 更新数据库中的filePath字段
            articleUncheckService.updateArticleUncheck(articleUncheck);
            return ajax;

        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 附件上传
     */
    @Anonymous
    @PostMapping("/attachment/{id}")
    public AjaxResult uploadAttachment(@PathVariable Long id, @RequestParam MultipartFile file) throws Exception {
        try {
            // 检查文件是否为空
            if (file.isEmpty()) {
                return AjaxResult.error("上传文件为空");
            }

            // 获取 base-path
            String basePath = "uncheckFiles/attachment/";

            // 指定oss保存文件路径
            String objectName = basePath + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/" + file.getOriginalFilename();
            // 上传文件，成功返回文件信息
            FileInfo fileInfo = fileStorageService.of(file).setPath(objectName).upload();

            // 设置返回结果
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", fileInfo.getUrl());
            ajax.put("fileName", fileInfo.getUrl());
            ajax.put("newFileName", fileInfo.getUrl());
            ajax.put("originalFilename", file.getOriginalFilename());

            // 先查询完整的ArticleUncheck对象
            ArticleUncheck articleUncheck = articleUncheckService.selectArticleUncheckByArticleId(id);
            if (articleUncheck != null) {
                // 更新attachment字段
                articleUncheck.setAttachment(fileInfo.getUrl());
                // 更新数据库中的attachment字段
                articleUncheckService.updateArticleUncheck(articleUncheck);
            }
            return ajax;

        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 审核表路径
     */
    @Anonymous
    @PostMapping("/appvalPath/{id}")
    public AjaxResult appvalPath(@PathVariable Long id, @RequestParam("appvalPath") MultipartFile appvalPath) throws Exception {
        try {
            // 检查文件是否为空
            if (appvalPath.isEmpty()) {
                return AjaxResult.error("上传文件为空");
            }

            // 获取 base-path
            String basePath = "uncheckFiles/appvalPath/";

            // 指定oss保存文件路径
            String objectName = basePath + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/" + appvalPath.getOriginalFilename();
            // 上传图片，成功返回文件信息
            FileInfo fileInfo = fileStorageService.of(appvalPath).setPath(objectName).upload();

            // 设置返回结果
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", fileInfo.getUrl());
            ajax.put("fileName", fileInfo.getUrl());  // 注意：这里的值要改为url，前端访问的地址,需要文件的地址 而不是文件名称
            ajax.put("newFileName", fileInfo.getUrl());
            ajax.put("originalFilename", appvalPath.getOriginalFilename());

            // 创建Article对象并设置ID和filePath
            ArticleUncheck articleUncheck = new ArticleUncheck();
            articleUncheck.setArticleId(id);
            articleUncheck.setAppval(fileInfo.getUrl());

            // 更新数据库中的filePath字段
            articleUncheckService.updateArticleUncheck(articleUncheck);

            return ajax;

        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 文章内容图片上传并替换为OSS路径
     */
    @PostMapping("/contentImage")
    public AjaxResult uploadContentImage(@RequestParam("file") MultipartFile file) throws Exception {
        try {
            // 检查文件是否为空
            if (file.isEmpty()) {
                return AjaxResult.error("上传文件为空");
            }

            // 获取 base-path
            String basePath = "articleContent/images/";

            // 指定oss保存文件路径
            String objectName = basePath + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/" + file.getOriginalFilename();
            // 上传图片，成功返回文件信息
            FileInfo fileInfo = fileStorageService.of(file).setPath(objectName).upload();

            // 设置返回结果
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", fileInfo.getUrl());
            ajax.put("fileName", fileInfo.getUrl());
            ajax.put("newFileName", fileInfo.getUrl());
            ajax.put("originalFilename", file.getOriginalFilename());

            return ajax;

        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }




    //审核后插入数据到article中
    @PostMapping("/audit")
    public AjaxResult audit(@RequestBody Article article){
        article.setAuditId(article.getArticleId());

        // 先插入文章
        int result = articleMapper.insertArticle(article);

        // 如果文章有PDF附件，异步解析PDF为图片
        if (result > 0 && article.getAttachment() != null && !article.getAttachment().isEmpty()) {
            // 检查附件是否为PDF文件
            if (article.getAttachment().toLowerCase().endsWith(".pdf")) {
                // 异步处理PDF解析任务
                pdfParseTaskService.processPdfParseTask(article.getArticleId());
            }
        }

        return toAjax(result);
    }

    //修改已审核数据，更新article
    @PutMapping("/updateToArticle")
    public AjaxResult updateToArticle(@RequestBody Article article){
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser sysUser = loginUser.getUser();
        //String userName = sysUser.getUserName();
        String ip = sysUser.getLoginIp();
        article.setIp(ip);
        article.setAuditId(article.getArticleId());
        return toAjax(articleMapper.updateToArticle(article));
    }

    //删除auditId对应的文章
    @DeleteMapping("/deleteAuditId/{auditId}")
    public AjaxResult deleteAuditId(@PathVariable Long auditId){
        // 使用新的方法，先检查是否存在再删除，避免删除失败的错误
        int result = articleMapper.deleteArticleByAuditId(auditId);
        // 无论是否删除成功，都返回成功，避免向用户显示错误提示（天才！）
        return success();
    }

    /**
     * 判断部门是否直接隶属于荆州市长江河道管理局（一级子部门）
     * @param dept 部门信息
     * @param sysDeptMapper 部门Mapper
     * @return 是否直接隶属于荆州市长江河道管理局
     */
    private static boolean isDirectSubDeptOfJingZhou(SysDept dept, SysDeptMapper sysDeptMapper) {
        // 如果部门本身就是"荆州市长江河道管理局"，则不认为是其下级部门
        if ("荆州市长江河道管理局".equals(dept.getDeptName())) {
            return false;
        }
        
        // 直接检查父部门是否为"荆州市长江河道管理局"
        // 如果父部门ID有效，直接查询父部门名称
        if (dept.getParentId() != null && dept.getParentId() > 0) {
            SysDept parentDept = sysDeptMapper.selectDeptById(dept.getParentId());
            if (parentDept != null && "荆州市长江河道管理局".equals(parentDept.getDeptName())) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 判断部门是否为市局/总局或其子部门
     * @param dept 部门信息
     * @param sysDeptMapper 部门Mapper
     * @return 是否为市局/总局或其子部门
     */
    private static boolean isCityBureauOrSubordinate(SysDept dept, SysDeptMapper sysDeptMapper) {
        if (dept == null) {
            return false;
        }
        
        // 如果当前部门就是市局/总局，直接返回true
        if ("市局/总局".equals(dept.getDeptName())) {
            return true;
        }
        
        // 通过祖先部门查找是否属于市局/总局
        String ancestors = dept.getAncestors();
        if (ancestors != null && !ancestors.isEmpty()) {
            // 从 ancestors 中提取所有祖先部门ID
            String[] ancestorIds = ancestors.split(",");
            
            // 查询祖先部门中是否有市局/总局
            for (String ancestorId : ancestorIds) {
                if (!ancestorId.trim().isEmpty()) {
                    try {
                        Long deptId = Long.parseLong(ancestorId.trim());
                        SysDept ancestorDept = sysDeptMapper.selectDeptById(deptId);
                        if (ancestorDept != null && "市局/总局".equals(ancestorDept.getDeptName())) {
                            return true;
                        }
                    } catch (NumberFormatException e) {
                        // 忽略无效ID
                    }
                }
            }
        }
        
        return false;
    }

    /**
     * 根据用户所属部门判断是否具有管理权限
     * @param sysUser 用户信息
     * @param sysDeptMapper 部门Mapper
     * @return 是否具有管理权限
     */
    private static boolean hasManagerPermission(SysUser sysUser, SysDeptMapper sysDeptMapper) {
        String userName = sysUser.getUserName();

        // 判断是否为管理员账户
        boolean isSuperAdmin = "admin".equals(userName);
        boolean hasManagerPermission = isSuperAdmin;

        // 如果不是超级管理员，则检查部门权限
        if (!isSuperAdmin && sysUser.getDept() != null) {
            // 获取用户所属部门
            String deptName = sysUser.getDept().getDeptName();
            SysDept dept = sysUser.getDept();

            // 根据部门类型判断权限：
            //先过滤掉市局/总局，然后再看是不是除市局/总局外的其他分局。再看是不是市局下面的部门。最后都排除了，只能是分局下的子部门了。
            if (deptName != null) {
                if ("市局/总局".equals(deptName)) {
                    // 市局/总局具有管理权限
                    hasManagerPermission = true;
                } else if (isDirectSubDeptOfJingZhou(dept, sysDeptMapper)) {
                    // 直接隶属于荆州市长江河道管理局的部门（分局）不具有管理权限
                    hasManagerPermission = false;
                } else if (isCityBureauOrSubordinate(dept, sysDeptMapper)) {
                    // 市局/总局的子部门具有管理权限
                    hasManagerPermission = true;
                } else {
                    // 其他部门，默认不具有管理权限
                    hasManagerPermission = false;
                }
            }
        }

        return hasManagerPermission;
    }

    /**
     * 获取用户部门对应的文章来源（分局名称）
     * 根据不同部门层级返回不同的权限控制策略：
     * 1. 分局用户：返回分局名称，可查看分局及子部门数据
     * 2. 子部门用户：返回子部门名称，仅可查看自己部门数据
     */
    private String getDeptArticleOrigin(SysUser sysUser) {
        if (sysUser.getDept() == null) {
            return null;
        }

        // 如果当前部门直接隶属于荆州市长江河道管理局（分局），直接返回
        if (isDirectSubDeptOfJingZhou(sysUser.getDept(), sysDeptMapper)) {
            return sysUser.getDept().getDeptName();
        }

        // 对于子部门用户，返回当前部门名称（只能查看自己部门数据）
        // 先检查是否为市局/总局或其子部门
        if (isCityBureauOrSubordinate(sysUser.getDept(), sysDeptMapper)) {
            // 市局/总局用户不需要articleOrigin过滤
            return null;
        }

        // 其他子部门用户，返回当前部门名称
        return sysUser.getDept().getDeptName();
    }



    /**
     * 查询uncheck列表 分局条件查询
     */
    @GetMapping("/list2")
    public TableDataInfo list2(ArticleUncheck articleUncheck) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser sysUser = loginUser.getUser();

        // 使用封装的权限判断方法
        boolean hasManagerPermission = hasManagerPermission(sysUser, sysDeptMapper);

        //部门id
        Long deptId = sysUser.getDept().getDeptId();

        // 如果是分局用户，添加部门权限过滤条件
        if (!hasManagerPermission && sysUser.getDept() != null) {
            String articleOrigin = getDeptArticleOrigin(sysUser);
            if (articleOrigin != null) {
                articleUncheck.setArticleOrigin(articleOrigin);
            }
        }

        startPage();
        List<ArticleUncheck> list = articleUncheckService.selectArticleListWithPermission(hasManagerPermission,deptId,articleUncheck);
        return getDataTable(list);
    }
    
    

    /**
     * 查询uncheck列表 权限版 市局默认，条件查询。分局默认查询
     */
//@PreAuthorize("@ss.hasPermi('uncheck:uncheck:list')")
    @GetMapping("/list")
    public Map<String, Object> list(ArticleUncheck articleUncheck) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser sysUser = loginUser.getUser();

        String userName = sysUser.getUserName();
        String dept = sysUser.getDept().getDeptName();
        //部门id
        Long deptId = sysUser.getDept().getDeptId();

        // 使用封装的权限判断方法
        boolean hasManagerPermission = hasManagerPermission(sysUser, sysDeptMapper);
        boolean canAdd = !hasManagerPermission;//分局权限
        boolean canAudit = hasManagerPermission;//管理员权限

        // 如果是分局用户，添加部门权限过滤条件
        if (!hasManagerPermission && sysUser.getDept() != null) {
                String articleOrigin = getDeptArticleOrigin(sysUser);
                if (articleOrigin != null) {
                    articleUncheck.setArticleOrigin(articleOrigin);
                }
            }

        startPage();
        List<ArticleUncheck> list = articleUncheckService.selectArticleListWithPermission(hasManagerPermission,deptId,articleUncheck);
        TableDataInfo tableDataInfo = getDataTable(list);
        HashMap<String, Object> result = new HashMap<>();
        result.put("data", tableDataInfo);
        result.put("userName", userName);
        result.put("canAdd", canAdd);
        result.put("canAudit", canAudit);
        result.put("isAdmin", articleUncheck.isAdmin());
        result.put("dept",dept);
        return result;
    }


    /**
     * 导出uncheck列表
     */
    @PreAuthorize("@ss.hasPermi('uncheck:uncheck:export')")
    @Log(title = "uncheck", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ArticleUncheck articleUncheck)
    {
        List<ArticleUncheck> list = articleUncheckService.selectArticleUncheckList(articleUncheck);
        ExcelUtil<ArticleUncheck> util = new ExcelUtil<ArticleUncheck>(ArticleUncheck.class);
        util.exportExcel(response, list, "uncheck数据");
    }

    /**
     * 获取uncheck详细信息
     */
    @PreAuthorize("@ss.hasPermi('uncheck:uncheck:query')")
    @GetMapping(value = "/{articleId}")
    public AjaxResult getInfo(@PathVariable("articleId") Long articleId)
    {
        return success(articleUncheckService.selectArticleUncheckByArticleId(articleId));
    }

    /**
     * 新增uncheck
     */
    @PreAuthorize("@ss.hasPermi('uncheck:uncheck:add')")
    @Log(title = "uncheck", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ArticleUncheck articleUncheck) throws ParseException
    {
        if (Objects.isNull(articleUncheck)){
            return error("请将数据填写完整");
        }
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser sysUser = loginUser.getUser();
        String userName = sysUser.getUserName();
        String ip = sysUser.getLoginIp();
        articleUncheck.setIp(ip);
        if (articleUncheck.getAuthor()!=null)
            articleUncheck.setAuthor(articleUncheck.getAuthor());
        else
            articleUncheck.setAuthor(userName);
        
        // 所有用户新增文章时都设置为未审核状态
        articleUncheck.setState("0");

        return toAjax(articleUncheckService.insertArticleUncheck(articleUncheck));
    }

    /**
     * 修改uncheck
     */
    @PreAuthorize("@ss.hasPermi('uncheck:uncheck:edit')")
    @Log(title = "uncheck", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ArticleUncheck articleUncheck)
    {
        // 获取原始文章状态
        ArticleUncheck originalArticle = articleUncheckService.selectArticleUncheckByArticleId(articleUncheck.getArticleId());

        // 如果原始文章存在且当前操作不是审核操作（state未被设置为1），则执行原有逻辑
        if (originalArticle != null && !"1".equals(articleUncheck.getState())) {
            String originalState = originalArticle.getState();

            // 无论市局还是分局用户，修改已审核的文章都变为未审核
            if ("1".equals(originalState)) {
                articleUncheck.setState("0"); // 已审核 -> 未审核
                articleUncheck.setClearPubdate(true); // 清除审核日期
                // 删除对应的已审核文章
                articleMapper.deleteArticleByAuditId(articleUncheck.getArticleId());
            }
            // 修改驳回或未审核的文章，状态保持未审核
            else if ("0".equals(originalState) || "2".equals(originalState)) {
                articleUncheck.setState("0"); // 驳回或未审核 -> 未审核
            }
        }
        // 如果是审核操作（state为1），则直接使用传入的状态值

        return toAjax(articleUncheckService.updateArticleUncheck(articleUncheck));
    }

    /**
     * 删除uncheck
     */
    @PreAuthorize("@ss.hasPermi('uncheck:uncheck:remove')")
    @Log(title = "uncheck", businessType = BusinessType.DELETE)
	@DeleteMapping("/{articleIds}")
    public AjaxResult remove(@PathVariable Long[] articleIds)
    {
        return toAjax(articleUncheckService.deleteArticleUncheckByArticleIds(articleIds));
    }

        
    /**
     * 逻辑删除
     */
    @PreAuthorize("@ss.hasPermi('uncheck:uncheck:remove')")
    @PostMapping("/logicDelete/{articleIds}")
    public TableDataInfo logicDelete(@PathVariable Long[] articleIds){
        List<RecoverStation> list = articleUncheckService.logicDeleteUncheck(articleIds);
        return getDataTable(list);
    }
}
